package com.hisense.hiioc.formtable.aspect;

import com.hisense.hiioc.formtable.util.JsonResult;
import com.hisense.hiioc.formtable.util.ResponseResult;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Arrays;
import java.util.List;

/**
 * 权限控制使用，暂时停用
 */
@Aspect
@Component
public class HttpAspect {

    private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);

    //表单权限控制
    @Pointcut("execution(public * com.hisense.hiioc.formtable.controller.FormController.*(..))")
    public void formController() {
    }

    //字段权限控制
    @Pointcut("execution(public * com.hisense.hiioc.formtable.controller.FieldController.*(..))")
    public void fieldController() {
    }

    //表操作权限控制
    @Pointcut("execution(public * com.hisense.hiioc.formtable.controller.OperateTableController.*(..))")
    public void operateTableController() {
    }

    @Around("fieldController() || formController() || operateTableController()")
    public Object around(ProceedingJoinPoint joinPoint) {

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        HttpSession session = request.getSession(false);
        if( session == null || session.getAttribute("username") == null || (String)session.getAttribute("username") == ""){
            return ResponseResult.Builder.buildError("您没有访问权限!");
        }

        try {
            return joinPoint.proceed();
        } catch (Throwable throwable) {
            return null;
        }
    }

    /**
     * 功能描述: 用@Before标识的方法为前置方法，在目标方法的执行之前执行，即在连接点之前进行执行。
     */
    @Before("fieldController() || formController() || operateTableController()")
    public void doBefore(JoinPoint joinPoint) {

    }

    /**
     * 功能描述: 后置方法在连接点方法完成之后执行，无论连接点方法执行成功还是出现异常，都将执行后置方法。
     */
    @After("fieldController() || formController() || operateTableController()")
    public void doAfter(JoinPoint point) {
        String methodName = point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName();
        List<Object> args = Arrays.asList(point.getArgs());
//        logger.info("doAfter()，方法：" + methodName + ",参数：" + args);
    }

    /**
     * 功能描述: 当连接点方法成功执行后，返回通知方法才会执行，如果连接点方法出现异常，则返回通知方法不执行
     */
    @AfterReturning(returning = "object", pointcut = "fieldController() || formController() || operateTableController()")
    public void doAfterReturning(JoinPoint point,Object object) {
        String methodName = point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName();
        List<Object> args = Arrays.asList(point.getArgs());
//        logger.info("doAfterReturning()，方法：" + methodName + ",参数：" + args + ",结果：" + object.toString());
    }

    /**
     * 功能描述: 异常通知方法只在连接点方法出现异常后才会执行，否则不执行
     *          通过throwing属性指定连接点方法出现异常信息存储在ex变量中，在异常通知方法中就可以从ex变量中获取异常信息了
     */
    @AfterThrowing(value = "execution(public * com.hisense.hiioc.formtable.controller.*.*(..)) ", throwing="ex")
    public void afterReturning(JoinPoint point, Exception ex){
        String methodName = point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName();
        List<Object> args = Arrays.asList(point.getArgs());
//        logger.info("doAfterThrowing()，方法：" + methodName + ",参数：" + args + ",异常：" + ex);
    }

}
